package com.beta.service.impl;

import com.baomidou.framework.service.impl.SuperServiceImpl;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.beta.dto.home.HomeBannersDto;
import com.beta.dto.product.ProductItemDto;
import com.beta.em.home.HomeBannerType;
import com.beta.entity.HomeBanners;
import com.beta.entity.Users;
import com.beta.mapper.HomeBannersMapper;
import com.beta.service.*;
import ma.glasnost.orika.MapperFacade;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 *
 * HomeBanners 表数据服务层接口实现类
 *
 */
@Service
public class HomeBannersService extends SuperServiceImpl<HomeBannersMapper, HomeBanners> implements IHomeBannersService {

    @Autowired
    private IProductItemsService productItemsService;
    @Autowired
    private IUsersService usersService;
    @Autowired
    private IDateTimeService dateTimeService;

    @Autowired
    private MapperFacade beanMapper;

    @Override
    public List<HomeBanners> getHomeBanners(Users user) {
        if (Objects.isNull(user)) {
            throw new ServiceException("E00113");
        }
        String cityCode = user.getCityCode();
        List<HomeBanners> homeBanners = selectList(new EntityWrapper<>(new HomeBanners().setCityCode(cityCode)).orderBy("position"));
        return homeBanners;
    }

    @Override
    public Page<HomeBannersDto> getHomeBannersPage(Page<HomeBannersDto> page) {
        List<HomeBannersDto> homeBannersDtos = baseMapper.selectHomeBannersPage(page);
        fillProductItemInfo(homeBannersDtos);
        page.setRecords(homeBannersDtos);
        return page;
    }

    @Override
    public HomeBannersDto getHomeBannerById(Integer id) {
        HomeBannersDto homeBannersDto = baseMapper.selectHomeBannerById(id);
        if (Objects.isNull(homeBannersDto)) {
            return null;
        }

        fillProductItemInfo(Arrays.asList(homeBannersDto));
        return homeBannersDto;
    }

    private void fillProductItemInfo(List<HomeBannersDto> homeBanners) {
        if (CollectionUtils.isEmpty(homeBanners)) {
            return ;
        }

        List<Integer> productItemIds = homeBanners.stream()
                .filter(homeBanner -> HomeBannerType.PRODUCTS.getValue().equals(homeBanner.getBannerType()))
                .map(HomeBannersDto::getProductItemId)
                .collect(Collectors.toList());
        if (CollectionUtils.isEmpty(productItemIds)) {
            return ;
        }

        List<ProductItemDto> productItems = productItemsService.getProductItemsBatchByIds(productItemIds);
        if (CollectionUtils.isEmpty(productItems)) {
            return ;
        }

        Map<Integer, ProductItemDto> productItemMap = productItems.stream()
                .collect(Collectors.toMap(ProductItemDto::getId, Function.identity()));
        homeBanners.forEach(homeBanner -> {
            boolean productType = HomeBannerType.PRODUCTS.getValue().equals(homeBanner.getBannerType());
            if (productType) {
                homeBanner.setProductItem(productItemMap.get(homeBanner.getProductItemId()));
            }
        });
    }

    @Override
    public void createHomeBanner(HomeBannersDto homeBannersDto) {
        if (Objects.isNull(homeBannersDto)) {
            throw new ServiceException("homeBanner.blank");
        }

        verifyBannerType(homeBannersDto);

        HomeBanners homeBanners = parseBannerFromDto(homeBannersDto);
        homeBanners.setCreatedAt(dateTimeService.toDbDate());
        insertSelective(homeBanners);
    }

    private void verifyBannerType(HomeBannersDto homeBannersDto) {
        HomeBannerType bannerType = HomeBannerType.getBannerType(homeBannersDto.getBannerType());
        if (Objects.isNull(bannerType)) {
            throw new ServiceException("homeBanner.type.invalid");
        }
    }

    private HomeBanners parseBannerFromDto(HomeBannersDto homeBannersDto) {
        HomeBanners homeBanners = new HomeBanners();
        homeBanners.setIsAvailable(Boolean.TRUE.equals(homeBannersDto.getAvailable()) ? 1: 0);
        homeBanners.setUpdatedAt(dateTimeService.toDbDate());

        HomeBannerType bannerType = HomeBannerType.getBannerType(homeBannersDto.getBannerType());
        switch (bannerType) {
            case NEWS:
                fillNewsInfo(homeBanners, homeBannersDto);
                break;
            case DEALER:
                fillDealerInfo(homeBanners, homeBannersDto);
                break;
            case PRODUCTS:
                fillProductItemInfo(homeBanners, homeBannersDto);
                break;
            default:
                throw new ServiceException("homeBanner.type.invalid");
        }

        return homeBanners;
    }

    private void fillNewsInfo(HomeBanners homeBanners, HomeBannersDto homeBannersDto) {
        homeBanners.setNewsUrl(homeBannersDto.getNewsUrl());
        homeBanners.setCityCode(homeBannersDto.getCityCode());
        homeBanners.setCityName(homeBannersDto.getCityName());
    }

    private void fillDealerInfo(HomeBanners homeBanners, HomeBannersDto homeBannersDto) {
        Users dealer = usersService.selectById(homeBannersDto.getUserId());
        homeBanners.setUserId(dealer.getId());
        homeBanners.setUserName(dealer.getName());
        homeBanners.setCityCode(dealer.getCityCode());
        homeBanners.setCityName(dealer.getCityName());
    }

    private void fillProductItemInfo(HomeBanners homeBanners, HomeBannersDto homeBannersDto) {
        ProductItemDto productItem = productItemsService.getProductItem(homeBannersDto.getProductItemId());
        homeBanners.setProductId(productItem.getProductId());
        homeBanners.setProductItemId(productItem.getId());
        homeBanners.setProductName(productItem.getName());
        homeBanners.setCityCode(productItem.getCityCode());
        homeBanners.setCityName(productItem.getCityName());
    }

    @Override
    public void updateHomeBannerById(Integer id, HomeBannersDto homeBannersDto) {
        if (Objects.isNull(id) || Objects.isNull(homeBannersDto)) {
            throw new ServiceException("homeBanner.blank");
        }

        HomeBanners homeBanners = parseBannerFromDto(homeBannersDto);
        homeBanners.setId(id);
        updateSelectiveById(homeBanners);
    }

}